#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
import re
import omen.tools.omen_tools as ft

## Configuration tools
# This module contains tools for configuration

## JSON configuration class
# Dictionnary object saved in JSON format
class JSONConf(object):
    ## load configuration from file
    # @param file_path the full path of the configuration file
    # @return an object representing the configuration
    @staticmethod    
    def load_from_file(file_path):
        # a json file may content comment
        return json.loads(clean_comments(ft.FileTools.read_text(file_path)))
    
    ## save configuration to file
    # @param conf the configuration object to save to disk
    # @param file_path the full path of the configuration file
    @staticmethod
    def save_to_file(conf, file_path):
        ft.FileTools.save_text(json.dumps(conf, indent=4), file_path)
    
    ## parse the configuration file to get a simpler configuration file (i.e. simple key:value configuration)
    # @param dico_conf the configuration data (a complex dictionary)
    
    @staticmethod
    def parse_to_pretty(dico_conf, base_key=""):
        result = {}
        for key in dico_conf.keys():
            value = dico_conf[key]
            if isinstance(value, dict):
                dico = JSONConf.parse_to_pretty(value, base_key + key+ ".")
                result.update(dico)
            else:
                result[base_key + key] = value
        
        
        return result

## Exception raised in case of error in configuration file
class ConfigurationCheckerError(RuntimeError):
    pass
        
class ConfigurationChecker(object):
    ## check that some keys are present in the configuration
    # @param conf the configuration object to check
    # @param keys_list the list of keys that must be present in the configuration object
    # @return 
    @staticmethod
    def check_keys(conf, keys_list):
        if not conf:
            raise ConfigurationCheckerError('No conf provided !')
        test = True
        key_ko = []
        for key in keys_list:
            if key not in conf.keys():
                key_ko.append(key)
                test = False
        if not test:
            raise ConfigurationCheckerError('Param(s) %s not present in configuration!' % (str(key_ko)))
        

# Regular expression for comments
comment_re = re.compile(
    '(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?',
    re.DOTALL | re.MULTILINE
)

def clean_comments(s_string):
#    a json file may accept comment but ignore it
#    see http://blog.getify.com/json-comments/
#    this code is inspired by damien riquet
#    http://www.lifl.fr/~riquetd/parse-a-json-file-with-comments.html
#    Comments look like :
#            // ...
#        or
#            /*
#            ...
#            */
    content = ''.join(s_string)
    ## Looking for comments
    match = comment_re.search(content)
    while match:
        # single line comment
        content = content[:match.start()] + content[match.end():]
        match = comment_re.search(content)
    
    return content
        